package com.util;

import com.alibaba.fastjson.JSONObject;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.ClassMapper;
import org.springframework.amqp.support.converter.DefaultClassMapper;
import org.springframework.amqp.support.converter.MessageConversionException;

import java.io.UnsupportedEncodingException;

public class FastJsonMessageConverter extends AbstractMessageConverter {

    private static final String DEFAULT_CHARSET = "UTF-8";

    private static ClassMapper classMapper =  new DefaultClassMapper();

    /**
     * 创建消息
     *
     * @param o
     * @param messageProperties
     * @return
     */
    @Override
    protected Message createMessage(Object o, MessageProperties messageProperties) {
        byte[] body = null;
        try {
            String json = JSONObject.toJSONString(o);
            body = json.getBytes(DEFAULT_CHARSET);
        } catch (UnsupportedEncodingException e) {
            throw new MessageConversionException("Failed to convert Message content from object", e);
        }
        messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON); // 内容类型
        messageProperties.setContentEncoding(DEFAULT_CHARSET); // 字符串编码
        if (body != null) {
            messageProperties.setContentLength(body.length);
        }
        // 将对象类型设置到messageProperties中，方便消费端取到消息之后进行类型转换
        classMapper.fromClass(o.getClass(), messageProperties);

        return new Message(body, messageProperties);
    }

    /**
     * 将消息转成对象
     *
     * @param message
     * @return
     * @throws MessageConversionException
     */
    @Override
    public Object fromMessage(Message message) throws MessageConversionException {
        Object o = null;
        MessageProperties properties = message.getMessageProperties();
        if (properties != null) {
            String contentType = properties.getContentType();
            // 内容类型匹配
            if (contentType != null && contentType.contains("json")) {
                // 获取字符串编码
                String encoding = properties.getContentEncoding();
                if (encoding == null) {
                    encoding = DEFAULT_CHARSET;
                }
                // 获取对象类型
                Class<?> targetClass = classMapper.toClass(message.getMessageProperties());
                try {
                    o = convertBytesToObject(message.getBody(), encoding, targetClass);
                } catch (UnsupportedEncodingException e) {
                    throw new MessageConversionException("Failed to convert object from Message content", e);
                }
            }
        }
        if (o == null) {
            o = message.getBody();
        }
        return o;
    }

    private Object convertBytesToObject(byte[] body, String encoding, Class<?> clazz) throws UnsupportedEncodingException {
        String contentAsString = new String(body, encoding);
        return JSONObject.parseObject(contentAsString, clazz);
    }
}
